from datetime import datetime

from flask import Flask,render_template,abort,flash,redirect,url_for,request
from flask_sqlalchemy import SQLAlchemy

from forms import NewsForm_mysql

app = Flask(__name__)
# 配置---数据库链接的配置参数
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@127.0.0.1/flask_news'
# 使用表单flask_wtf 需要配置一个SECRET_KEY  配置就行 具体使用不知
app.config['SECRET_KEY'] = 'this is a random key string'
# flask和SQLAlchemy关联一下
db = SQLAlchemy(app)


# 创建新闻模型类（继承db.model）
class News(db.Model):
    # 新闻模型
    __tablename__ = 'news'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False, comment='标题')
    img_url = db.Column(db.String(200), nullable=False, comment='主图地址')
    content = db.Column(db.String(200), nullable=False, comment='新闻内容')
    is_valid = db.Column(db.Boolean, default=True, comment='逻辑删除')
    is_top = db.Column(db.Boolean, default=True, comment='是否置顶')
    created_at = db.Column(db.DateTime, default=datetime.now(), comment='创建时间')
    updated_at = db.Column(db.DateTime, default=datetime.now(), comment='最后修改时间')
    news_type = db.Column(db.Enum('本地', '百家', '娱乐', '军事'), comment='新闻类别')


# 创建好模型类，需要同步到数据库中
# 1.在python console中  输入
# from app import db （app是app.py）
# db.create_all()即可(使用这个报错了  没有上下文的错误)

# 使用modelToDatabase可以，定位到当前目录
# 定位到当前目录的方式（打开设置File → Settings → Build, Execution, Deployment → Console → Python Console。）
# 在Working directory中填写目标路径，例如（D:\freedong\zhuzhu\FullStackEngineer2025\507python_operate_three_databases\4.flask_news(自动生成)）
# 在python console中  输入
# 执行from app import modelToDatabase 然后执行modelToDatabase()模型同步到数据库成功
def modelToDatabase():
    with app.app_context():
        db.create_all()

# 前台页面--首页
@app.route('/')
def index():  # put application's code here
    news_list = News.query.filter(News.is_valid == 1,News.is_top == 1).all()
    print(news_list[0])
    return render_template('index.html',news_list=news_list)

# 前台页面--分类
@app.route('/cat/<news_type>')
def cat(news_type):
    # 新闻分类页
    news_list = News.query.filter(News.news_type == news_type,News.is_valid == 1).all()
    print(news_list)
    return render_template('cat.html',news_list=news_list,news_type=news_type)

# 前台页面--新闻详情页
@app.route('/detail/<pk>')
def detail(pk):
    # 新闻详情页
    new_obj = News.query.get(pk)
    if not new_obj.is_valid:
        abort(404)
    return render_template('detail.html',new_obj=new_obj)


# 后台管理--新闻首页
@app.route('/admin/')
@app.route('/admin/<int:page>/')
def admin(page=1):
    # 后台管理 - -新闻首页
    # 第一种分页方式  前端页面循环用page_data
    # page_size = 3
    # offset = (page - 1) * page_size
    # page_data = News.query.limit(page_size).offset(offset)
    # 第二种分页方式  前端页面循环用page_data.items
    page_data = News.query.filter(News.is_valid == 1).paginate(page=page,per_page=3)
    # 第二种方式的page_data  是一个对象里面有很多属性和方法items、has_prev、iter_pages()等等  前端页面可以调用
    return render_template('admin/index.html',page_data=page_data)

# 后台管理--新增新闻(/admin/add和/admin/add/ 有时报404  是浏览器缓存问题)
@app.route("/admin/add",methods=("GET","POST"))
def news_add():
    # "新增新闻"
    form = NewsForm_mysql()
    if form.validate_on_submit():
        news_obj = News(
            title=form.title.data,
            content=form.content.data,
            img_url=form.img_url.data,
            news_type=form.news_type.data,
            created_at=datetime.now()
        )
        # 保存数据
        db.session.add(news_obj)
        db.session.commit()
        flash("新增成功")
        return redirect(url_for('admin'))
    else:
        print("表单添加失败")
    return render_template("admin/add.html",form=form)

# 后台管理--修改新闻
@app.route("/admin/update/<int:pk>",methods=["GET","POST"])
def news_update(pk):
    # '后台管理--修改新闻'
    new_obj = News.query.get(pk)
    print(new_obj)
    if new_obj is None:
        abort(404)
    form = NewsForm_mysql(obj = new_obj)
    if request.method == 'POST':
        if form.validate_on_submit():
            print(form.title.data)
            print(form.content.data)
            print(form.news_type.data)
            new_obj.title = form.title.data
            new_obj.content = form.content.data
            # new_obj.img_url = form.img_url.data
            new_obj.news_type = form.news_type.data
            new_obj.updated_at = datetime.now()
            db.session.add(new_obj)
            db.session.commit()
            print('修改成功')
            flash('修改成功','success')
            return redirect('/admin/')
        else:
            flash('你的表单中还有错误，请修改','danger')
            print('表单没有通过验证',form.errors)

    return render_template("admin/update.html",form=form)

# 后台管理--删除新闻
@app.route("/admin/delete/<pk>",methods=['POST'])
def news_delete(pk):
    # 异步ajax删除 逻辑删除
    if request.method == 'POST':
        obj = News.query.get(pk)
        if obj is None:
            return 'no'
        obj.is_valid = False
        db.session.add(obj)
        db.session.commit()
        return 'yes'
    return 'no'

# 后台管理--查看新闻(前台有详情  此处没必要)
@app.route("/admin/detail/<pk>",methods=['GET'])
def news_detail(pk):
    pass
    # # 新闻详情页
    # new_obj = News.query.get(pk)
    # if not new_obj.is_valid:
    #     abort(404)
    # return render_template('admin/update.html', new_obj=new_obj)


if __name__ == '__main__':
    app.run()
    # app.run(host='127.0.0.1', port=8088, debug=True)  # 必须指定 host
